#第九章 面向对象程序设计

#9-1 定义student类的私有属性和私有方法
class Student:
    def __init__(self,score):
        self.__score=score
    def __get_score(self):
        return self.__score
s1=Student(100)
print(s1._Student__score)
print(s1._Student__get_score())

#9-2 定义Score类，将其属性权限设置为只读
class Score:
    def __init__(self,data):
        self.__data=data
    @property
    def data(self):
        return f"私有属性的值为{self.__data}"
s1=Score(60)
print(s1.data)

#9-3 将Score类中的属性权限设置为可读写
class Score:
    def __init__(self,data):
        self.__data=data
    @property
    def data(self):
        return f"私有属性的值为{self.__data}"
    @data.setter
    def data(self,value):
        if value<0 or value>100:
            raise ValueError("您的输入有误，输入范围为0~100")
        else:
            self.__data=value
s1=Score(60)
print(s1.data)
s1.data=100
print(s1.data)

#9-4 动物和狗、猫的继承关系
class Animal:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(f"{self.name}正在吃东西")
    def sleep(self):
        print(f"{self.name}正在睡觉")
class Dog(Animal):
    pass
class Cat(Animal):
    def play(self):
        print(f"{self.name}正在玩耍")
if __name__=="__main__":
    my_dog=Dog("小汪",4)
    my_dog.eat()
    my_cat=Cat("小喵",2)
    my_cat.play()
    
#9-5 重写Dog类中的构造方法    
class Animal:
    def __init__(self,name,age):
        self.name=name
        self.age=age
class Dog(Animal):
    def __init__(self,name,age,vaccine):
        super().__init__(name, age)
        self.vaccine=vaccine
if __name__=="__main__":
    my_dog=Dog("小汪",4,"True")
    if my_dog.vaccine:
        print(f"{my_dog.name}打过疫苗了")
    else:
        print(f"{my_dog.name}还没打过疫苗")
        
#9-6 重写Cat类中的eat()方法
class Animal:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(f"{self.name}正在吃东西")
class Cat(Animal):
    def eat(self):
        print(f"{self.name}正在吃猫粮")
if __name__=="__main__":
    my_cat=Cat("小喵",2)
    my_cat.eat()
    
#9-7 职员、学生与非全日制学生的多重继承关系
class Student:
    def __init__(self,name,score):
        self.name=name
        self.score=score
    def stu_info(self):
        print(f"姓名:{self.name},分数:{self.score}")
class Staff:
    def __init__(self,id,salary):
        self.id=id
        self.salary=salary
    def staff_info(self):
        print(f"ID:{self.id},薪资:{self.salary}")
class PartTimeStudent(Student,Staff):
    def __init__(self, name, score,id,salary):
        Student.__init__(self, name, score)
        Staff.__init__(self, id, salary)
p1=PartTimeStudent("小千", 100, "202201", 10000)
p1.stu_info()
p1.staff_info()

#9-8 几何图形求面积的多态体现
import math
class Graphic :
    def __init__(self,name) -> None:
        self.name = name
    def cal_square(self):
        pass
class Triangle (Graphic) :
    def __init__(self, name,height,broder) -> None:
        super().__init__(name)
        self.height = height
        self.broder = broder
    def cal_square(self):
        square = 1/2 * self.height * self.broder
        print(f"{self.name}面积为{square:.2f}")
class Circle(Graphic) :
    def __init__(self, name,radius) -> None:
        super().__init__(name)
        self.radius = radius
    def cal_square(self):
        square = math.pi * pow(self.radius,2)
        print(f"{self.name}面积为{square:.3f}")
t1 = Triangle("三角形",6,8)
t1.cal_square()
c1 = Circle("圆",3)
c1.cal_square()

#9-9 定义一个Clock类，不重写内置函数
class Clock:
    def __init__(self,hour,minute,second):
        self.hour=hour
        self.minute=minute
        self.second=second
c1= Clock(2,30,20)
print(c1)

#9-10 定义一个Clock类，重写内置函数
class Clock :
    def __init__(self,hour,minute,second) -> None:
        self.hour = hour
        self.minute = minute
        self.second = second
    def __str__(self) -> str:
        return f"时{self.hour}分{self.minute}秒{self.second}"
    def __repr__(self) :
        return f"Clock({self.hour},{self.minute},{self.second})"
c1 = Clock(10,20,30)
print(c1)
c2 = eval(repr(c1))
c2.hour = 1
print(c2)

#9-11 计算接力赛的赛跑长度及时长，并判断获胜队伍
class Race :
    def __init__(self,length,time) -> None:
        self.length = length
        self.time   = time
    def __add__(self,other) :
        return Race(self.length + other.length,self.time + other.time)
    def __gt__(self,other) :
        if self.length == other.length :
            return self.time > other.time
        else :
            raise TypeError("无法比较")
    def __eq__(self, other) :
        if self.length == other.length:
            return self.time == other.time
        else :
            raise TypeError("无法比较")
    def __str__(self) :
        return f"赛跑长度:{self.length},时长{self.time}"
if __name__ == "__main__" :
    team1_1 = Race(200,20)
    team1_2 = Race(200,19.7)
    team1   = team1_1 + team1_2
    print(team1)
    team2_1 = Race(200,16.3)
    team2_2 = Race(200,19.7)
    team2   = team2_1 + team2_2
    print(team2)
    if team1 > team2 :
        print("team1 Win")
    elif team1 == team2 :
        print("No Porle Win")
    else :
        print("team2 Win")

#9-12 isinstance()函数的使用
class Employee:
    pass
e1=Employee()
if isinstance(e1,Employee):
    print("e1属于Employee的实例对象")
else:
    print("e1不属于Employee的实例对象")

#9-13 模拟薪资结算
class Employee :
    def __init__(self,name) -> None:
        self.name = name
    def get_salary(self) :
        pass
class Manager(Employee) :
    def __init__(self, name,salary=15000) -> None:
        super().__init__(name)
        self.salary = salary
    def get_salary(self):
        return self.salary
    def __str__(self) :
        return f"{self.name}的薪资为{self.get_salary()}"
class Programmer(Employee) :
    def __init__(self, name,base_salary=12000,over_time=0) -> None:
        super().__init__(name)
        self.base_salary = base_salary
        self.__over_time = over_time
    def get_salary(self):
        if self.__over_time < 0 :
            raise ValueError("输入工作时长有误")
        elif self.__over_time > 20 :
            self.__over_time = 20 
        return self.base_salary + 100 * self.__over_time
    def __str__(self) -> str:
        return f"{self.name}的薪资为{self.get_salary()}"
class SoftTest(Employee) :
    def __init__(self, name,base_salary=8000,bug_num=0) -> None:
        super().__init__(name)
        self.base_salary = base_salary
        self.bug_num = bug_num
    def get_salary(self):
        return self.base_salary + 5 * self.bug_num
    def __str__(self) -> str:
        return f"{self.name}的薪资为{self.get_salary()}"
def main():
    Employee_list = [
        Manager("Nun1"),Manager("Nun2"),Manager("Nun3",1000),
        Programmer("Mun1"),Programmer("Mun2",1000,10),Programmer("Mun3",1000,20),
        SoftTest("Bun1"),SoftTest("Bun2"),SoftTest("Bun3",9000,100),
    ]
    for emp in Employee_list :
        if isinstance(emp,Programmer) :
            print("程序员",emp)
        elif isinstance(emp,Programmer) :
            print("产品经理",emp)    
        else :
            print("测试工程师",emp)
if __name__ == "__main__" :
    main()

#9-14 自定义异常类AgeError
class AgeError(Exception):
    def __init__(self,error_info):
        self.error_info=error_info
    def __str__(self):
        return self.error_info
age=int(input("请输入年龄："))
if age<18 or age>200:
    raise AgeError("年龄不在成年人范围内！")
else:
    print("年龄是：",age)

#9-15 捕获自定义异常类AgeError
class AgeError(Exception):
    def __init__(self,error_info):
        self.error_info=error_info
    def __str__(self):
        return self.error_info
age=int(input("请输入年龄："))
try:
    if age<18 or age>200:
        raise AgeError("年龄不在成年人范围内！")
    else:
        print("年龄是：",age)
except AgeError as a:
    print(a.error_info)